package com.plian.system.service.cqzc.bondissue;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.cache.UserCache;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.constant.yth.YthConstant;
import com.plian.system.dao.bt.baseinfo.BaseInfoDao;
import com.plian.system.dao.cqzc.bondissue.bondIssueDao;
import com.plian.system.dao.cqzc.bondsapply.BondsApplyDao;
import com.plian.system.dao.cqzc.bondsrepayment.BondsRepaymentDao;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.entity.fr.bonds.BondsApply;
import com.plian.system.entity.fr.bonds.BondsIssue;
import com.plian.system.entity.sys.ApprovalMessage;
import com.plian.system.entity.sys.IgnoreMessageInfo;
import com.plian.system.entity.sys.Message;
import com.plian.system.mapper.fr.bonds.BondsIssueMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.service.bt.baseinfo.BaseInfoService;
import com.plian.system.service.cqzc.bondsapply.BondsApplyService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.message.IApprovalMessageService;
import com.plian.system.service.sys.message.IIgnoreMessageInfoService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.pm.bond.BondSummaryInfoVO;
import com.plian.system.vo.yth.YthResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.plian.system.constant.sys.FormStatusConstant.*;
import static com.plian.system.constant.sys.FormTypeConstant.CQZC_BONDISSUE;

/**
 * 说明：债券发行
 */
@Slf4j
@Service
public class BondsIssueService extends ServiceImpl<BondsIssueMapper, BondsIssue> implements BaseFlowService {
    @Autowired
    bondIssueDao bondissueDao;
    @Autowired
    FileService fileService;
    @Autowired
    BondsApplyDao bondsApplyDao;
    @Autowired
    FormWorkflowService formWorkflowService;
    @Autowired
    BondsRepaymentDao bondsrepaymentDao;
    @Autowired
    IFormCodeService formCodeService;
    @Autowired
    BondsApplyDao bondsapplyDao;
    @Autowired
    BaseInfoDao baseInfoDao;
    @Autowired
    BondsRepaymentDao bondsRepaymentDao;
    @Autowired
    bondIssueDao bondIssueDao;
    @Autowired
    OrgzationDao orgzationDao;
    @Autowired
    BaseInfoService baseInfoService;
    @Autowired
    IIgnoreMessageInfoService ignoreMessageInfoService;
    @Autowired
    IOrgService orgService;
    @Autowired
    BondsApplyService bondsApplyService;
    @Autowired
    private IApprovalMessageService approvalMessageService;

    /**
     * logger属性.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(BondsIssueService.class);


    /**
     * 保存
     *
     * @param pd
     * @return
     */
    public ObjResult save(PageData pd) {
        try {
            isData(pd);
            String id = UuidUtil.get32UUID();
            pd.put("id", id);
            pd.put("status", "0");
            pd.put("orgId", TokenUtil.getTokenOrgId());
            pd.put("createDate", new Date());
            pd.put("code", formCodeService.getCode(FormTypeConstant.CQZC_BONDISSUE));
            pd.put("formType", FormTypeConstant.CQZC_BONDISSUE);
            pd.put("createUser", TokenUtil.getTokenUserId());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("updateTime", new Date());
            checkIssueName(pd);
            bondissueDao.save(pd);
            //保存附件
            fileService.saveAll(id, (List<HashMap>) pd.get("list_doc"));
            HashMap<String, Object> processVariable = new HashMap<>();
            formWorkflowService.startProcessAndSimulate(id, pd.getString("formType"), processVariable);
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (MyRuntimeException e) {
            throw e;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }


    public void goBackToStash(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(UNREVIEWED));
            pageData.put("id", Collections.singletonList(formId));
            bondissueDao.refer(pageData);
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
    }


    /**
     * 校验可用额度
     *
     * @return
     */
    public void isData(PageData pd) throws Exception {
        //发行金额
        double issueAmount = Tools.isEmpty(pd.getString("issueAmount")) ? 0 : Double.valueOf(pd.getString("issueAmount"));
        //剩余可发金额
        double remainingIssuableAmount1 = Tools.isEmpty(pd.getString("remainingIssuableAmount")) ? 0 : Double.valueOf(pd.getString("remainingIssuableAmount"));
        //剩余发行金额
        double remainingIssuableAmount = Double.valueOf(remainingIssuableAmount(pd.getString("bondsApplyId")));
        if (pd.containsKey("isReport")) {
            if (remainingIssuableAmount != remainingIssuableAmount1) {
                ObjResult objResult = new ObjResult(CommonCode.VALIDATE);
                objResult.setMessage("剩余可发行金额发生改变,请重新保存后上报!!!");
                throw new MyRuntimeException(objResult);
            }
        }
        if (issueAmount > remainingIssuableAmount) {
            ObjResult objResult = new ObjResult(CommonCode.VALIDATE);
            objResult.setMessage("剩余可发行金额不足!!!");
            throw new MyRuntimeException(objResult);
        }
    }

    /**
     * 修改
     *
     * @param pd
     * @return
     */
    public ObjResult edit(PageData pd) {
        try {
            String id = pd.getString("id");
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("updateTime", new Date());
            checkIssueName(pd);
            bondissueDao.edit(pd);
            //修改附件
            fileService.edit(id, (List<HashMap>) pd.get("list_doc"));
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (MyRuntimeException e) {
            throw e;
        }  catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    private void checkIssueName(PageData pd) throws  Exception{
        PageData oldPd = bondissueDao.findByIssueName(pd.getString("name"));
        if (!Optional.ofNullable(oldPd).isPresent()){
            return;
        }
        if (pd.getString("id").equals(oldPd.getString("id"))){
            return;
        }
        throw new MyRuntimeException(new ObjResult("发行债券名称重复"));
    }


    /**
     * 查询列表
     *
     * @return
     */
    public ListResult listPage(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            Page page = new Page(isPage, pd);
            List<PageData> list = bondissueDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }


    public ListResult reportList(PageData pd) throws Exception {
        ListResult listResult;
        try {
            Page page = new Page(false, pd);
            List<PageData> list = bondissueDao.reportListPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 查询列表
     *
     * @return
     */
    public ListResult issueList(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            Page page = new Page(true, pd);
            List<PageData> list = bondissueDao.issueList(page);


            PageData p1 = new PageData();
            p1.put("status", "1");
            p1.put("orgId", TokenUtil.getTokenOrgId());
            Page page1 = new Page(false, p1);
            List<PageData> list1 = bondsrepaymentDao.listPage(page1);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(RemainingBalance(list, list1));

            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    public List<Message> noRepaymentList(){
        List<Message> messages = new ArrayList<>();
        try {
            List<PageData> issueList = bondIssueDao.noRepaymentList();
            if (CollectionUtil.isEmpty(issueList)){
                return new ArrayList<>();
            }
            PageData repayPage = new PageData();
            repayPage.put("issueIds", issueList.stream()
                    .map(issue -> issue.getString("id")).collect(Collectors.toList()));
            List<PageData> repaymentList = bondsRepaymentDao.reportList(repayPage);
            Map<String, List<PageData>> repaymentMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(repaymentList)){
                repaymentMap = repaymentList.stream().collect(Collectors.groupingBy(repayment -> repayment.getString("formId")));
            }

            List<String> noCheckFormIds = ignoreMessageInfoService.list(Wrappers.<IgnoreMessageInfo>lambdaQuery()
                            .eq(IgnoreMessageInfo::getFormType, FormTypeConstant.CQZC_BONDISSUE)).stream()
                    .filter(ignoreMessageInfo -> StringUtil.isNotBlank(ignoreMessageInfo.getFormId()))
                    .map(IgnoreMessageInfo::getFormId).collect(Collectors.toList());

            for (PageData issue : issueList){
                String formId = issue.getString("formId");
                if (noCheckFormIds.contains(formId)){
                    continue;
                }
                BigDecimal sumRepay = new BigDecimal("0");
                String bondIssueId = issue.getString("bondIssueId");
                if(repaymentMap.containsKey(bondIssueId)){
                    for(PageData repayment : repaymentMap.get("bondIssueId")){
                        String sumRepaymentOfPrincipal = repayment.getString("repaymentOfPrincipal");
                        if (Tools.notEmpty(sumRepaymentOfPrincipal)) {
                            sumRepay = sumRepay.add(new BigDecimal(sumRepaymentOfPrincipal));
                        }
                    }
                }

                //发行金额
                String issueAmount = issue.getString("issueAmount");
                if (Tools.isEmpty(issueAmount)) {
                    issueAmount = "0";
                }
                BigDecimal bIssueAmount = new BigDecimal(issueAmount);
                BigDecimal remainingBalance = bIssueAmount.subtract(sumRepay);
                if (remainingBalance.compareTo(new BigDecimal(0)) == 1) {
                    Message message = Message.builder().createUser(issue.getString("createUser"))
                            .formId(issue.getString("formId")).formTypeName("债券发行")
                            .formType(issue.getString("formType"))
                            .orgId(issue.getString("orgId"))
                            .orgName(issue.getString("orgName"))
                            .messageTime(DateUtil.parse(issue.getString("messageTime"), DateUtil.PATTERN_DATE))
                            .message("已到期")
                            .build();
                    messages.add(message);

                }
            }

        } catch (Exception e){
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
        return messages;
    }


    /**
     * @param list 发行 列表
     * @param l    偿还列表
     * @return
     * @throws Exception
     */
    private List<PageData> RemainingBalance(List<PageData> list, List<PageData> l) throws Exception {
        List<PageData> list1 = new ArrayList<>();
        //累计已偿还金额
        for (PageData apply : list) {
            BigDecimal sumRepay = new BigDecimal("0");
            for (PageData p1 : l) {
                if (apply.getString("id").equals(p1.getString("bondIssueId"))) {
                    String sumRepaymentOfPrincipal = p1.getString("repaymentOfPrincipal");
                    if (Tools.notEmpty(sumRepaymentOfPrincipal)) {
                        sumRepay = sumRepay.add(new BigDecimal(sumRepaymentOfPrincipal));
                    }
                }
            }

            //发行金额
            String issueAmount = apply.getString("issueAmount");
            if (Tools.isEmpty(issueAmount)) {
                issueAmount = "0";
            }
            BigDecimal b_issueAmount = new BigDecimal(issueAmount);
            BigDecimal remainingBalance = b_issueAmount.subtract(sumRepay);
            if (remainingBalance.floatValue() != 0) {
                //存续余额
                apply.put("remainingBalance", remainingBalance.toPlainString());
                list1.add(apply);
            }

        }

        return list1;

    }

    private void setApplyList(PageData pd, List<PageData> applyList,  List<PageData> issueList,  List<PageData> repaymentList) throws Exception{
        //发债申请
        List<PageData> temporaryApplyList = bondsApplyDao.list(pd);

        if(CollectionUtil.isEmpty(temporaryApplyList)){
           return;
        }

        applyList.addAll(temporaryApplyList);
        List<String> bondsApplyIds = new ArrayList<>();
        for (PageData pageData : applyList) {
            bondsApplyIds.add(pageData.getString("id"));
        }
        //发债发行

        List<String> issueIds = new ArrayList<>();
        if (bondsApplyIds != null && bondsApplyIds.size() > 0) {
            pd.put("bondsApplyIds", bondsApplyIds);
            List<PageData> temporaryIssueList = bondissueDao.list(pd);
            if (CollectionUtil.isEmpty(temporaryIssueList)){
               return;
            }
            issueList.addAll(temporaryIssueList);
        }
        //债券偿还

        if (issueList != null && issueList.size() > 0) {
            pd.remove("bondsApplyIds");
            for (PageData pageData : issueList) {
                issueIds.add(pageData.getString("id"));
            }
            if (issueIds != null && issueIds.size() > 0) {
                pd.put("issueIds", issueIds);
                List<PageData> temporaryRepaymentList = bondsRepaymentDao.reportList(pd);
                if (CollectionUtil.isEmpty(temporaryRepaymentList)){
                    return;
                }
                repaymentList.addAll(temporaryRepaymentList);
            }
        }
    }

    // TODO DEL
//    public ReportReturnVO applySummaryDetail(PageData pd) throws Exception{
//        List<PageData> applyList = new ArrayList<>();
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//        setApplyList(pd, applyList, issueList, repaymentList);
//
//        List<BondSummaryDetailVO> results = new ArrayList<>();
//        String endTimeStr = pd.getString("endTime");
//        long endTime = DateUtil.parse(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_DATE), DateUtil.PATTERN_DATE).getTime();
//        if (StringUtil.isNotBlank(endTimeStr)){
//            endTime =  DateUtil.parse(endTimeStr, DateUtil.PATTERN_DATE).getTime();
//        }
//        if(CollectionUtil.isNotEmpty(applyList)){
//            for (PageData apply : applyList){
//                BondSummaryDetailVO detailVO = BondSummaryDetailVO.builder()
//                        .issuerName(apply.getString("issuerName"))
//                        .registrationApprovalNumber(apply.getString("registrationApprovalNumber"))
//                        .declaredAmount(BigDecimalUtil.toBigdecimal(apply.getString("quota")))
//                        .bondApplyId(apply.getString("id"))
//                        .build();
//
//                BigDecimal issueAmount = new BigDecimal(0);
//                BigDecimal balanceAmount = new BigDecimal(0);
//                List<BondIssuerVO> issuerVOS = new ArrayList<>();
//                for (PageData issue : issueList) {
//                    if (issue.getString("bondsApplyId")
//                            .equals(apply.getString("id"))) {
//                        issueAmount = (BigDecimalUtil.add(issueAmount, BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
//                        balanceAmount = BigDecimalUtil.add(balanceAmount, BigDecimalUtil.toBigdecimal(issue.getString("issueAmount")));
//
//                        BondIssuerVO bondIssuerVO = BondIssuerVO.builder().bondName(issue.getString("name"))
//                                .issueAmount(BigDecimalUtil.toBigdecimal(issue.getString("issueAmount")))
//                                .bondIssuerId(issue.getString("id")).build();
//                        issuerVOS.add(bondIssuerVO);
//
//                        List<BondRepaymentVO> repaymentVOS = new ArrayList<>();
//
//                        //偿还
//                        for (PageData repayment : repaymentList) {
//                            if (repayment.getString("bondIssueId").equals(issue.getString("id"))) {
//                                BondRepaymentVO bondRepaymentVO = BondRepaymentVO.builder()
//                                        .repaymentDate(DateUtil.parse(repayment.getString("repaymentDate"), DateUtil.PATTERN_DATETIME))
//                                        .repaymentOfPrincipal(BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal")))
//                                        .bondRepaymentId(repayment.getString("id"))
//                                        .build();
//
//                                repaymentVOS.add(bondRepaymentVO);
//                                balanceAmount = BigDecimalUtil.subtract(balanceAmount,
//                                        BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal")));
//                            }
//                        }
//
//                        bondIssuerVO.setBondRepaymentVOS(repaymentVOS);
//                    }
//                }
//                detailVO.setBondIssuerVOList(issuerVOS);
//
//                //非超短期
//                if ("5".equals(apply.getString("bondVarieties"))) {
//                    detailVO.setSurplusAmount(BigDecimalUtil.subtract(detailVO.getDeclaredAmount(), balanceAmount));
//                } else {
//                    detailVO.setSurplusAmount(BigDecimalUtil.subtract(detailVO.getDeclaredAmount(), issueAmount));
//                }
//                String effectiveDeadline = apply.getString("effectiveDeadline");
//                if(StringUtil.isNotBlank(effectiveDeadline)){
//                    long deadLine = DateUtil.parse(effectiveDeadline, DateUtil.PATTERN_DATETIME).getTime();
//                    if(deadLine < endTime){
//                        detailVO.setSurplusAmount(new BigDecimal(0));
//                    }
//                }
//                detailVO.setBalanceAmount(balanceAmount);
//                detailVO.setRatio(BigDecimalUtil.divide(issueAmount, detailVO.getDeclaredAmount(), 2, BigDecimal.ROUND_HALF_UP, 100));
//                results.add(detailVO);
//            }
//        }
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("issuerName").title("发债主体").build())
//                .addHeader(HeaderVO.builder().key("registrationApprovalNumber").title("注册批准文号").build())
//                .addHeader(HeaderVO.builder().key("declaredAmount").title("申报额度（万元）").build())
//                .addHeader(HeaderVO.builder().key("surplusAmount").title("剩余可用额度（万元）").build())
//                .addHeader(HeaderVO.builder().key("balanceAmount").title("存续债券余额（万元）").build())
//                .addHeader(HeaderVO.builder().key("ratio").title("已发行比例%").build())
//                .addHeader(HeaderVO.builder().key("bondName").title("发行债券名称").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（万元）").build())
//                .addHeader(HeaderVO.builder().key("repaymentOfPrincipal").title("本期偿还金额（万元）").build())
//                .addHeader(HeaderVO.builder().key("repaymentDate").title("偿还日期").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

//    public ReportReturnVO issueSummary(PageData pd) throws Exception{
//        List<PageData> applyList = new ArrayList<>();
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//        setApplyList(pd, applyList, issueList, repaymentList);
//        //根据企业级次分组 升序
//        Map<String, List<PageData>> gradeApplyMap = Maps.newLinkedHashMap();
//        applyList.stream().filter(item -> StringUtil.isNotBlank(item.getString("enterpriseGrade"))).
//                collect(Collectors.groupingBy(e -> e.getString("enterpriseGrade")))
//                .entrySet().stream().sorted(Map.Entry.comparingByKey())
//                .forEachOrdered(e -> gradeApplyMap.put(e.getKey(), e.getValue()));
//
//        Map<String, String> enterpriseRankMap = baseInfoService.getChildMap(ValueSetConstant.ENTERPRISE_RANK);
//        BondSummaryInfoVO totalVO = BondSummaryInfoVO.builder().enterpriseGradeName("总计").isSummary(2).build();
//        List<BondSummaryInfoVO> results = new ArrayList<>();
//
//        String endTimeStr = pd.getString("endTime");
//        long endTime = DateUtil.parse(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_DATE), DateUtil.PATTERN_DATE).getTime();
//        if (StringUtil.isNotBlank(endTimeStr)){
//            endTime =  DateUtil.parse(endTimeStr, DateUtil.PATTERN_DATE).getTime();
//        }
//
//        List<String> totalOrgIds = new ArrayList<>();
//        for (String enterpriseGrade : gradeApplyMap.keySet()){
//            String gradeName = enterpriseRankMap.get(enterpriseGrade);
//            BondSummaryInfoVO subtotalVO = BondSummaryInfoVO.builder().enterpriseGradeName(gradeName + "企业合计").isSummary(2)
//                    .enterpriseGrade(enterpriseGrade).build();
//            List<String> subtotalOrgIds = new ArrayList<>();
//            List<PageData> gradeApplyList = gradeApplyMap.get(enterpriseGrade);
//
//            Map<String, List<PageData>> issuerMap = gradeApplyList.stream().
//                    collect(Collectors.groupingBy(e -> e.getString("issuer")));
//            String enterpriseGradeName = gradeName + "（"+ issuerMap.keySet().size() + "家）";
//
//            for (String issuer : issuerMap.keySet()){
//                List<PageData> issuerApplyList = issuerMap.get(issuer);
//                totalOrgIds.add(issuer);
//                subtotalOrgIds.add(issuer);
//                BondSummaryInfoVO issuerVO = BondSummaryInfoVO.builder().enterpriseGradeName(enterpriseGradeName)
//                        .issuerName(issuerApplyList.get(0).getString("issuerName"))
//                        .issuer(issuer).issuers(Stream.of(issuer).collect(Collectors.toList())).isSummary(1).build();
//                applyValueSet(issuerVO, issuerApplyList, issueList, repaymentList, endTime);
//
//                issuerVO.setRatio(BigDecimalUtil.divide(issuerVO.getBalanceAmount(),
//                        issuerVO.getDeclaredAmount(), 2 , BigDecimal.ROUND_HALF_UP, 100));
//
//                subtotalVO.setDeclaredAmount(BigDecimalUtil.add(subtotalVO.getDeclaredAmount(), issuerVO.getDeclaredAmount()));
//                subtotalVO.setSurplusAmount(BigDecimalUtil.add(subtotalVO.getSurplusAmount(), issuerVO.getSurplusAmount()));
//                subtotalVO.setIssueAmount(BigDecimalUtil.add(subtotalVO.getIssueAmount(), issuerVO.getIssueAmount()));
//                subtotalVO.setBalanceAmount(BigDecimalUtil.add(subtotalVO.getBalanceAmount(), issuerVO.getBalanceAmount()));
//
//                amountUnitSet(issuerVO);
//                results.add(issuerVO);
//            }
//            subtotalVO.setIssuers(subtotalOrgIds);
//            subtotalVO.setRatio(BigDecimalUtil.divide(subtotalVO.getBalanceAmount(),
//                    subtotalVO.getDeclaredAmount(), 2 , BigDecimal.ROUND_HALF_UP, 100));
//
//            totalVO.setDeclaredAmount(BigDecimalUtil.add(subtotalVO.getDeclaredAmount(), totalVO.getDeclaredAmount()));
//            totalVO.setSurplusAmount(BigDecimalUtil.add(subtotalVO.getSurplusAmount(), totalVO.getSurplusAmount()));
//            totalVO.setIssueAmount(BigDecimalUtil.add(subtotalVO.getIssueAmount(), totalVO.getIssueAmount()));
//            totalVO.setBalanceAmount(BigDecimalUtil.add(subtotalVO.getBalanceAmount(), totalVO.getBalanceAmount()));
//            amountUnitSet(subtotalVO);
//            results.add(subtotalVO);
//        }
//
//        totalVO.setIssuers(totalOrgIds);
//        totalVO.setRatio(BigDecimalUtil.divide(totalVO.getBalanceAmount(),
//                totalVO.getDeclaredAmount(), 2 , BigDecimal.ROUND_HALF_UP, 100));
//        amountUnitSet(totalVO);
//        results.add(totalVO);
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("enterpriseGradeName").title("发债主体级别").build())
//                .addHeader(HeaderVO.builder().key("issuerName").title("发债主体").build())
//                .addHeader(HeaderVO.builder().key("declaredAmount").title("申报额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("surplusAmount").title("剩余可用额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("balanceAmount").title("存续债券余额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("ratio").title("已发行比例%").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

    /**
     * 债券申请相关数据
     * @param infoVO
     * @param groupApplyList
     * @param issueList
     * @param repaymentList
     * @param endTime
     */
    private void applyValueSet(BondSummaryInfoVO infoVO, List<PageData> groupApplyList,
                               List<PageData> issueList, List<PageData> repaymentList, long endTime){
        for (PageData apply : groupApplyList) {
            infoVO.setDeclaredAmount(BigDecimalUtil.add(infoVO.getDeclaredAmount(),
                    BigDecimalUtil.toBigdecimal(apply.getString("quota"))));

            for (PageData issue : issueList) {
                if (issue.getString("bondsApplyId").equals(apply.getString("id"))) {
                    issueValueSet(infoVO, issue, repaymentList);
                }
            }

            BigDecimal surplusAmount;
            //非超短期
            if ("5".equals(apply.getString("bondVarieties"))) {
                surplusAmount = BigDecimalUtil.subtract(BigDecimalUtil.toBigdecimal(apply.getString("quota")), infoVO.getTempBalanceAmount());
            } else {
                surplusAmount = BigDecimalUtil.subtract(BigDecimalUtil.toBigdecimal(apply.getString("quota")), infoVO.getTempIssueAmount());
            }

            String effectiveDeadline = apply.getString("effectiveDeadline");
            if(StringUtil.isNotBlank(effectiveDeadline)){
                long deadLine = DateUtil.parse(effectiveDeadline, DateUtil.PATTERN_DATETIME).getTime();
                if(deadLine < endTime){
                    surplusAmount = new BigDecimal(0);
                }
            }
            infoVO.setTempBalanceAmount(null);
            infoVO.setTempIssueAmount(null);
            infoVO.setSurplusAmount(BigDecimalUtil.add(infoVO.getSurplusAmount(), surplusAmount));
        }
    }


    /**
     * 债券发行相关数据
     * @param infoVO
     * @param issue
     * @param repaymentList
     */
    private void issueValueSet(BondSummaryInfoVO infoVO, PageData issue, List<PageData> repaymentList){
        infoVO.setIssueAmount(BigDecimalUtil.add(infoVO.getIssueAmount(),
                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
        infoVO.setBalanceAmount(BigDecimalUtil.add(infoVO.getBalanceAmount(),
                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));

        infoVO.setTempIssueAmount(BigDecimalUtil.add(infoVO.getTempIssueAmount(),
                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
        infoVO.setTempBalanceAmount(BigDecimalUtil.add(infoVO.getTempBalanceAmount(),
                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
        //偿还
        for (PageData repayment : repaymentList) {
            if (repayment.getString("bondIssueId").equals(issue.getString("id"))) {
                infoVO.setBalanceAmount(BigDecimalUtil.subtract(infoVO.getBalanceAmount(),
                        BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal"))));
                infoVO.setTempBalanceAmount(BigDecimalUtil.subtract(infoVO.getTempBalanceAmount(),
                        BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal"))));
            }
        }
    }

    private void amountUnitSet(BondSummaryInfoVO bondSummaryInfoVO){
        bondSummaryInfoVO.setDeclaredAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getDeclaredAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setSurplusAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getSurplusAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setIssueAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getIssueAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setBalanceAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getBalanceAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setExtensionAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getExtensionAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setAddAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getAddAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setAddIssueAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getAddIssueAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
        bondSummaryInfoVO.setExpireAmount(BigDecimalUtil.divide(bondSummaryInfoVO.getExpireAmount(),
                new BigDecimal(10000), 6, BigDecimal.ROUND_HALF_UP));
    }

//    public ReportReturnVO typeSummary(PageData pd) throws Exception{
//        List<PageData> applyList = new ArrayList<>();
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//        setApplyList(pd, applyList, issueList, repaymentList);
//        //根据债券类型分组 升序
//        Map<String, List<PageData>> typeApplyMap = applyList.stream().filter(item -> StringUtil.isNotBlank(item.getString("enterpriseGrade"))).
//                collect(Collectors.groupingBy(e -> e.getString("bondVarieties")));
//
//        List<String> orgIds = (List<String>)pd.get("orgIds");
//        BondSummaryInfoVO totalVO = BondSummaryInfoVO.builder().bondTypeName("总计").orgIds(orgIds).build();
//        List<BondSummaryInfoVO> results = new ArrayList<>();
//        HashMap<String, String> bondTypeMap = getBondTypeMap();
//
//        String endTimeStr = pd.getString("endTime");
//        long endTime = DateUtil.parse(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_DATE), DateUtil.PATTERN_DATE).getTime();
//        if (StringUtil.isNotBlank(endTimeStr)){
//            endTime =  DateUtil.parse(endTimeStr, DateUtil.PATTERN_DATE).getTime();
//        }
//
//        for (String bondType : typeApplyMap.keySet()){
//            String bondTypeName = bondTypeMap.get(bondType);
//            BondSummaryInfoVO bondTypeVO = BondSummaryInfoVO.builder().bondTypeName(bondTypeName)
//                    .bondTypes(Stream.of(bondType).collect(Collectors.toList())).orgIds(orgIds).build();
//
//            List<PageData> typeApplyList = typeApplyMap.get(bondType);
//            applyValueSet(bondTypeVO, typeApplyList, issueList, repaymentList, endTime);
//
//            totalVO.setDeclaredAmount(BigDecimalUtil.add(bondTypeVO.getDeclaredAmount(), totalVO.getDeclaredAmount()));
//            totalVO.setIssueAmount(BigDecimalUtil.add(bondTypeVO.getIssueAmount(), totalVO.getIssueAmount()));
//            totalVO.setBalanceAmount(BigDecimalUtil.add(bondTypeVO.getBalanceAmount(), totalVO.getBalanceAmount()));
//
//            amountUnitSet(bondTypeVO);
//            results.add(bondTypeVO);
//        }
//
//        amountUnitSet(totalVO);
//        results.add(totalVO);
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("bondTypeName").title("债券品种").build())
//                .addHeader(HeaderVO.builder().key("declaredAmount").title("申报额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("实际发行金额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("balanceAmount").title("存续债券余额（亿元）").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

    private HashMap<String, String> getBondTypeMap(){
        HashMap<String, String> bondTypeMap = new HashMap<>(16);
        bondTypeMap.put("0", "企业债券");
        bondTypeMap.put("1", "公司债券");
        bondTypeMap.put("2", "中期票据");
        bondTypeMap.put("3", "短期融资券");
        bondTypeMap.put("4", "非定向公开债务融资工具");
        bondTypeMap.put("5", "超短期融资券");
        bondTypeMap.put("6", "永续中票");
        bondTypeMap.put("7", "其他");
        bondTypeMap.put("8", "非金融企业债券融资工具");
        bondTypeMap.put("9", "资产证券化");
        bondTypeMap.put("10", "保险资金");
        bondTypeMap.put("11", "保险资金投资计划");
        bondTypeMap.put("12", "可续期公司债券");
        return bondTypeMap;
    }

//    public ReportReturnVO yearSummary(PageData pd) throws Exception{
//        //发债发行
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//
//        setIssueList(pd, issueList, repaymentList);
//        Map<String, List<PageData>> issueReleaseDeadlineMap = issueListToMapByReleaseDeadline(issueList);
//        List<String> orgIds = (List<String>)pd.get("orgIds");
//
//        List<BondSummaryInfoVO> results = new ArrayList<>();
//        BondSummaryInfoVO totalVO = BondSummaryInfoVO.builder().releaseDeadline("合计").orgIds(orgIds).build();
//        for (String releaseDeadline : issueReleaseDeadlineMap.keySet()){
//            List<PageData> issueReleaseDeadlineList = issueReleaseDeadlineMap.get(releaseDeadline);
//
//            BondSummaryInfoVO infoVO = BondSummaryInfoVO.builder().releaseDeadline(releaseDeadline).orgIds(orgIds).build();
//            for (PageData issue : issueReleaseDeadlineList){
//                issueValueSet(infoVO, issue, repaymentList );
//            }
//
//            totalVO.setIssueAmount(BigDecimalUtil.add(totalVO.getIssueAmount(), infoVO.getIssueAmount()));
//            totalVO.setBalanceAmount(BigDecimalUtil.add(totalVO.getBalanceAmount(), infoVO.getBalanceAmount()));
//
//            amountUnitSet(infoVO);
//            results.add(infoVO);
//        }
//        results = results.stream().sorted(Comparator.comparing(BondSummaryInfoVO::getSortNumber)).collect(Collectors.toList());
//        amountUnitSet(totalVO);
//        results.add(totalVO);
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("releaseDeadline").title("债券发行期限").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("balanceAmount").title("存续余额（亿元）").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

//    public ReportReturnVO yearSummaryDetail(PageData pd) throws Exception{
//        //发债发行
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//
//        setIssueList(pd, issueList, repaymentList);
//
//        Map<String, List<PageData>> issueReleaseDeadlineMap = issueListToMapByReleaseDeadline(issueList);
//        String releaseDeadline = pd.getString("releaseDeadline");
//        List<PageData> issueResultList = new ArrayList<>();
//        if (StringUtil.isNotBlank(releaseDeadline) && !"合计".equals(releaseDeadline)){
//            if (issueReleaseDeadlineMap.containsKey(releaseDeadline)){
//                issueResultList.addAll(issueReleaseDeadlineMap.get(releaseDeadline));
//            }
//        }else {
//            issueResultList.addAll(issueList);
//        }
//
//        List<BondIssuerVO> results = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(issueResultList)){
//            for (PageData issue : issueResultList) {
//                BondIssuerVO bondIssuerVO = BondIssuerVO.builder().bondName(issue.getString("name"))
//                        .issueAmount(BigDecimalUtil.toBigdecimal(issue.getString("issueAmount")))
//                        .bondValueDate(DateUtil.parse(issue.getString("bondValueDate"), DateUtil.PATTERN_DATETIME))
//                        .bondMaturity(DateUtil.parse(issue.getString("bondMaturity"), DateUtil.PATTERN_DATETIME))
//                        .bondIssuerId(issue.getString("id")).build();
//                results.add(bondIssuerVO);
//                List<BondRepaymentVO> repaymentVOS = new ArrayList<>();
//
//                //偿还
//                for (PageData repayment : repaymentList) {
//                    if (repayment.getString("bondIssueId").equals(issue.getString("id"))) {
//                        BondRepaymentVO bondRepaymentVO = BondRepaymentVO.builder()
//                                .repaymentDate(DateUtil.parse(repayment.getString("repaymentDate"), DateUtil.PATTERN_DATETIME))
//                                .repaymentOfPrincipal(BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal")))
//                                .build();
//
//                        repaymentVOS.add(bondRepaymentVO);
//                    }
//                }
//                bondIssuerVO.setBondRepaymentVOS(repaymentVOS);
//            }
//        }
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("bondName").title("发行债券名称").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（万元）").build())
//                .addHeader(HeaderVO.builder().key("bondValueDate").title("起息日").build())
//                .addHeader(HeaderVO.builder().key("bondMaturity").title("到期日").build())
//                .addHeader(HeaderVO.builder().key("repaymentOfPrincipal").title("本期偿还金额（万元）").build())
//                .addHeader(HeaderVO.builder().key("repaymentDate").title("偿还日期").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

    /**
     * 债券发行 数组  按发行期限分组
     * @param issueList
     * @return
     */
    private Map<String, List<PageData>> issueListToMapByReleaseDeadline(List<PageData> issueList){
        /**
         * 过滤 起息日或 到期日为空的数据
         */
        issueList = issueList.stream().filter(issue ->
                StringUtil.isNotBlank(issue.getString("bondValueDate"))
                        && StringUtil.isNotBlank(issue.getString("bondMaturity")))
                .collect(Collectors.toList());

        issueList.forEach(issue -> {
            LocalDate startDate = LocalDate.parse(issue.getString("bondValueDate"), DateUtil.DATETIME_FORMATTER);
            LocalDate endDate = LocalDate.parse(issue.getString("bondMaturity"), DateUtil.DATETIME_FORMATTER);
            Period period = Period.between(startDate, endDate);
            int years = period.getYears();
            int months = period.getMonths();
            int days = period.getDays();
            issue.put("releaseDeadline", getReleaseDeadline(years, months, days));
        });

         return issueList.stream()
                .collect(Collectors.groupingBy(e -> e.getString("releaseDeadline")));
    }

    private String getReleaseDeadline(int years, int months, int days){

        if (years == 0 || (years == 1 && months == 0 && days == 0)){
            return "1年（含）以内";
        }

        if ((years > 0 && years < 3) || (years == 3 &&  months == 0 && days == 0)){
            return "1-3年（含）以内";
        }

        if ((years >= 3 && years < 5) || (years == 5 &&  months == 0 && days == 0)){
            return "3-5年（含）以内";
        }

        if ((years >= 5 && years < 10) || (years == 10 &&  months == 0 && days == 0)){
            return "5-10年（含）以内";
        }

        return "其他";
    }

    private void setIssueList(PageData pd,  List<PageData> issueList,  List<PageData> repaymentList) throws Exception{
        List<String> issueIds = new ArrayList<>();
        List<PageData> temporaryIssueList = bondissueDao.yearList(pd);
        if (CollectionUtil.isEmpty(temporaryIssueList)){
            return;
        }
        issueList.addAll(temporaryIssueList);
        //债券偿还
        if (CollectionUtil.isNotEmpty(issueList)) {
            for (PageData pageData : issueList) {
                issueIds.add(pageData.getString("id"));
            }
            if (CollectionUtil.isNotEmpty(issueIds)) {
                pd.put("issueIds", issueIds);
                List<PageData> temporaryRepaymentList = bondsRepaymentDao.reportList(pd);
                if (CollectionUtil.isEmpty(temporaryRepaymentList)){
                    return;
                }
                repaymentList.addAll(temporaryRepaymentList);
            }
        }
    }

    //TODO DEL
//    public ReportReturnVO expirationYearSummary(PageData pd) throws Exception{
//        List<PageData> issueList = bondissueDao.yearList(pd);
//        List<String> orgIds = (List<String>)pd.get("orgIds");
//
//        List<BondSummaryInfoVO> results = new ArrayList<>();
//        BondSummaryInfoVO totalVO = BondSummaryInfoVO.builder().expirationYear("合计").orgIds(orgIds).build();
//        LocalDateTime nowTime = LocalDateTime.now();
//        //当前年
//        int thisYear = nowTime.getYear();
//
//        Map<Integer, List<PageData>> issueYearMap = issueList.stream().filter(issue ->
//                StringUtil.isNotBlank(issue.getString("year")))
//                .collect(Collectors.groupingBy(issue -> issue.getInteger("year")));
//        List<Integer> years = issueYearMap.keySet().stream().sorted(Comparator.comparing(year -> year)).collect(Collectors.toList());
//        for (Integer expirationYear : years){
//            BondSummaryInfoVO infoVO = BondSummaryInfoVO.builder().year(expirationYear)
//                    .expirationYear(expirationYear + "年").orgIds(orgIds).build();
//            List<PageData> list = issueYearMap.get(expirationYear);
//            for (PageData issue : list) {
//                infoVO.setIssueAmount(BigDecimalUtil.add(infoVO.getIssueAmount(),
//                        BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
//                String extensionPeriod = issue.getString("extensionPeriod");
//                if (Tools.notEmpty(extensionPeriod) && !"0".equals(extensionPeriod)) {
//                    infoVO.setExtensionAmount(BigDecimalUtil.add(infoVO.getExtensionAmount(),
//                            BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
//                }
//            }
//            totalVO.setIssueAmount(BigDecimalUtil.add(totalVO.getIssueAmount(), infoVO.getIssueAmount()));
//            totalVO.setExtensionAmount(BigDecimalUtil.add(totalVO.getExtensionAmount(), infoVO.getExtensionAmount()));
//            amountUnitSet(infoVO);
//            results.add(infoVO);
//        }
//
//        amountUnitSet(totalVO);
//        results.add(totalVO);
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("expirationYear").title("存续债券到期年份").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("extensionAmount").title("具有延期选择权债券金额（亿元）").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

//    public ReportReturnVO expirationYearSummaryDetail(PageData pd) throws Exception{
//        //发债发行
//        List<PageData> issueList = bondissueDao.yearList(pd);
//
//        Map<Integer, List<PageData>> issueYearMap = issueList.stream().filter(issue ->
//                StringUtil.isNotBlank(issue.getString("year")))
//                .collect(Collectors.groupingBy(issue -> issue.getInteger("year")));
//        String year = pd.getString("year");
//        List<PageData> issueResultList = new ArrayList<>();
//        if (StringUtil.isNotBlank(year)){
//            if (issueYearMap.containsKey(Integer.valueOf(year))){
//                issueResultList.addAll(issueYearMap.get(Integer.valueOf(year)));
//            }
//        }else {
//            issueResultList.addAll(issueList);
//        }
//        List<BondIssuerVO> results = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(issueResultList)){
//            for (PageData issue : issueResultList) {
//                BondIssuerVO bondIssuerVO = BondIssuerVO.builder().bondName(issue.getString("name"))
//                        .issueAmount(BigDecimalUtil.toBigdecimal(issue.getString("issueAmount")))
//                        .bondValueDate(DateUtil.parse(issue.getString("bondValueDate"), DateUtil.PATTERN_DATETIME))
//                        .bondMaturity(DateUtil.parse(issue.getString("bondMaturity"), DateUtil.PATTERN_DATETIME))
//                        .bondIssuerId(issue.getString("id")).build();
//                results.add(bondIssuerVO);
//            }
//        }
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("bondName").title("发行债券名称").build())
//                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（万元）").build())
//                .addHeader(HeaderVO.builder().key("bondValueDate").title("起息日").build())
//                .addHeader(HeaderVO.builder().key("bondMaturity").title("到期日").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

    //TODO DEL
//    public ReportReturnVO bondAnalysis(PageData pd) throws Exception{
//        List<PageData> applyList = new ArrayList<>();
//        List<PageData> issueList = new ArrayList<>();
//        List<PageData> repaymentList = new ArrayList<>();
//        setApplyList(pd, applyList, issueList, repaymentList);
//        //根据所属集团分组
//        Map<String, List<PageData>> groupCompanyApplyMap = applyList.stream().filter(item -> StringUtil.isNotBlank(item.getString("enterpriseGrade"))).
//                collect(Collectors.groupingBy(e -> e.getString("groupCompany")));
//
//        List<String> orgIds = (List<String>)pd.get("orgIds");
//        BondSummaryInfoVO totalVO = BondSummaryInfoVO.builder().groupCompanyName("总计").orgIds(orgIds).build();
//        List<BondSummaryInfoVO> results = new ArrayList<>();
//
//        //当前年
//        LocalDateTime nowTime = LocalDateTime.now();
//        int thisYear = nowTime.getYear();
//        String endTimeStr = pd.getString("endTime");
//        if(StringUtil.isNotBlank(endTimeStr)){
//            thisYear = Integer.valueOf(endTimeStr.split("-")[0]);
//        }
//
//
//        long endTime = DateUtil.parse(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_DATE), DateUtil.PATTERN_DATE).getTime();
//        if (StringUtil.isNotBlank(endTimeStr)){
//            endTime =  DateUtil.parse(endTimeStr, DateUtil.PATTERN_DATE).getTime();
//        }
//
//        for (String groupCompany : groupCompanyApplyMap.keySet()){
//            List<PageData> groupCompanyApplyList = groupCompanyApplyMap.get(groupCompany);
//            BondSummaryInfoVO infoVO = BondSummaryInfoVO.builder()
//                    .groupCompanyName(groupCompanyApplyList.get(0).getString("groupCompanyName"))
//                    .orgIds(Stream.of(groupCompany).collect(Collectors.toList())).build();
//
//            for (PageData apply : groupCompanyApplyList){
//                String quota = apply.getString("quota");
//                infoVO.setDeclaredAmount(BigDecimalUtil.add(infoVO.getDeclaredAmount(),
//                        BigDecimalUtil.toBigdecimal(quota)));
//
//                String registrationDate = apply.getString("registrationDate");
//
//                if (StringUtil.isNotBlank(registrationDate)){
//                    int regYear= Integer.parseInt(registrationDate.substring(0,4));
//                    if(regYear==thisYear){
//                        infoVO.setAddAmount(BigDecimalUtil.add(infoVO.getAddAmount(),
//                                BigDecimalUtil.toBigdecimal(quota)));
//                    }
//                }
//
//                for (PageData issue : issueList) {
//                    if (issue.getString("bondsApplyId").equals(apply.getString("id"))) {
//                        String issueAmount = issue.getString("issueAmount");
//                        infoVO.setIssueAmount(BigDecimalUtil.add(infoVO.getIssueAmount(),
//                                BigDecimalUtil.toBigdecimal(issueAmount)));
//                        infoVO.setBalanceAmount(BigDecimalUtil.add(infoVO.getBalanceAmount(),
//                                BigDecimalUtil.toBigdecimal(issueAmount)));
//
//                        infoVO.setTempIssueAmount(BigDecimalUtil.add(infoVO.getTempIssueAmount(),
//                                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
//                        infoVO.setTempBalanceAmount(BigDecimalUtil.add(infoVO.getTempBalanceAmount(),
//                                BigDecimalUtil.toBigdecimal(issue.getString("issueAmount"))));
//
//                        String bondValueDate = issue.getString("bondValueDate");
//                        if (StringUtil.isNotBlank(bondValueDate)){
//                            int bondValueYear = Integer.parseInt(bondValueDate.substring(0,4));
//                            if(bondValueYear == thisYear){
//                                infoVO.setAddIssueAmount(BigDecimalUtil.add(infoVO.getAddIssueAmount(),
//                                        BigDecimalUtil.toBigdecimal(issueAmount)));
//                            }
//                        }
//
//                        String bondMaturity = issue.getString("bondMaturity");
//                        if (StringUtil.isNotBlank(bondMaturity)){
//                            int bondMaturityYear = Integer.parseInt(bondMaturity.substring(0,4));
//                            if(bondMaturityYear == thisYear){
//                                infoVO.setExpireAmount(BigDecimalUtil.add(infoVO.getExpireAmount(),
//                                        BigDecimalUtil.toBigdecimal(issueAmount)));
//                            }
//                        }
//
//                        //偿还
//                        for (PageData repayment : repaymentList) {
//                            if (repayment.getString("bondIssueId").equals(issue.getString("id"))) {
//                                infoVO.setBalanceAmount(BigDecimalUtil.subtract(infoVO.getBalanceAmount(),
//                                                BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal"))));
//                                infoVO.setTempBalanceAmount(BigDecimalUtil.subtract(infoVO.getTempBalanceAmount(),
//                                        BigDecimalUtil.toBigdecimal(repayment.getString("repaymentOfPrincipal"))));
//                            }
//                        }
//                    }
//                }
//
//                //非超短期
//                BigDecimal surplusAmount;
//                if ("5".equals(apply.getString("bondVarieties"))) {
//                    surplusAmount = BigDecimalUtil.subtract(BigDecimalUtil.toBigdecimal(apply.getString("quota")),
//                            infoVO.getTempBalanceAmount());
//                } else {
//                    surplusAmount = BigDecimalUtil.subtract(BigDecimalUtil.toBigdecimal(apply.getString("quota")),
//                            infoVO.getTempIssueAmount());
//                }
//                String effectiveDeadline = apply.getString("effectiveDeadline");
//                if(StringUtil.isNotBlank(effectiveDeadline)){
//                    long deadLine = DateUtil.parse(effectiveDeadline, DateUtil.PATTERN_DATETIME).getTime();
//                    if(deadLine < endTime){
//                        surplusAmount = new BigDecimal(0);
//                    }
//                }
//                infoVO.setSurplusAmount(BigDecimalUtil.add(infoVO.getSurplusAmount(), surplusAmount));
//                infoVO.setTempBalanceAmount(null);
//                infoVO.setTempIssueAmount(null);
//            }
//
//
////            totalVO.setDeclaredAmount(BigDecimalUtil.add(infoVO.getDeclaredAmount(), totalVO.getDeclaredAmount()));
//            totalVO.setSurplusAmount(BigDecimalUtil.add(infoVO.getSurplusAmount(), totalVO.getSurplusAmount()));
////            totalVO.setIssueAmount(BigDecimalUtil.add(infoVO.getIssueAmount(), totalVO.getIssueAmount()));
//            totalVO.setBalanceAmount(BigDecimalUtil.add(infoVO.getBalanceAmount(), totalVO.getBalanceAmount()));
//            totalVO.setAddAmount(BigDecimalUtil.add(infoVO.getAddAmount(), totalVO.getAddAmount()));
//            totalVO.setAddIssueAmount(BigDecimalUtil.add(infoVO.getAddIssueAmount(), totalVO.getAddIssueAmount()));
//            totalVO.setExpireAmount(BigDecimalUtil.add(infoVO.getExpireAmount(), totalVO.getExpireAmount()));
//
//
//            amountUnitSet(infoVO);
//            results.add(infoVO);
//        }
//
//        amountUnitSet(totalVO);
//        results.add(totalVO);
//
//        ReportReturnVO reportReturnVO = new ReportReturnVO();
//        ReportVO reportVO = new ReportVO();
//        reportVO
//                .addHeader(HeaderVO.builder().key("groupCompanyName").title("出资企业").build())
////                .addHeader(HeaderVO.builder().key("declaredAmount").title("申报额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("surplusAmount").title("剩余可用额度（亿元）").build())
////                .addHeader(HeaderVO.builder().key("issueAmount").title("发行金额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("balanceAmount").title("存续债券余额（亿元）").build())
//                .addHeader(HeaderVO.builder().key("addAmount").title("年度新增注册额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("addIssueAmount").title("年度新增发行额度（亿元）").build())
//                .addHeader(HeaderVO.builder().key("expireAmount").title("年内到期债券金额（亿元）").build());
//        reportVO.setData(results);
//        reportReturnVO.setGrids(reportVO);
//        return reportReturnVO;
//    }

    /**
     * 债券报表
     *
     * @param pd
     * @return
     */
    public ObjResult report(PageData pd) throws Exception {
//        if(!pd.containsKey("orgIds")){
//            ObjResult objResult=new ObjResult(CommonCode.ERRORPARAMETER);
//            objResult.setMessage("请选择单位!!!");
//            return objResult;
//        }
        //维度
        List<String> dimensions = (List<String>) pd.get("dimensions");
        List<PageData> list = new ArrayList<>();
        TreeUtli treeUtli = new TreeUtli();
        if (dimensions != null && dimensions.size() > 0) {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);

            for (String dimension : dimensions) {
                PageData p = new PageData();
                if ("1".equals(dimension) || "2".equals(dimension)) {

                    List<PageData> applyList = new ArrayList<>();
                    List<PageData> issueList = new ArrayList<>();
                    List<PageData> repaymentList = new ArrayList<>();
                    setApplyList(pd, applyList, issueList, repaymentList);

                    if ("1".equals(dimension)) {
                        //企业级次
//                       List<String> parentId=new ArrayList<>();
//                       parentId.add("001");
//                       PageData p_o=new PageData();
//                       p_o.put("parentId",parentId);
//                       List<Tree>  baseInfoDaoTree=baseInfoDao.findTree(p_o);
//                       p.put("dimensions1",subject(applyList,issueList,baseInfoDaoTree,repaymentList));
                        list.add(subject(applyList, issueList, null, repaymentList));
                    }
                    if ("2".equals(dimension)) {
//                       p.put("dimensions2",varieties(applyList,issueList,repaymentList));
                        list.addAll(varieties(applyList, issueList, repaymentList));
                    }
                }
                if ("3".equals(dimension) || "4".equals(dimension)) {
                    //发债发行
                    List<PageData> issueList = bondissueDao.yearList(pd);
                    List<String> issueIds = new ArrayList<>();
                    //债券偿还
                    List<PageData> repaymentList = new ArrayList<>();
                    for (PageData pageData : issueList) {
                        issueIds.add(pageData.getString("id"));
                    }
                    if (issueList != null && issueList.size() > 0) {
                        if (issueIds != null && issueIds.size() > 0) {
                            pd.put("issueIds", issueIds);
                            repaymentList = bondsRepaymentDao.reportList(pd);
                        }
                    }
                    if ("3".equals(dimension)) {
                        list.addAll(term(issueList, repaymentList));
                    }
                    if ("4".equals(dimension)) {
                        list.addAll(year(issueList, repaymentList));
                    }
                }
                if ("5".equals(dimension)) {
                    //当前登录企业
                    String orgId = TokenUtil.getTokenOrgId();
                    //当前登录企业的相关信息
                    PageData org = orgzationDao.findbyid(orgId);

                    //如果为国资
                    if ("0".equals(org.getString("parentId"))) {
                        //得到所有集团
                        List<PageData> units = orgzationDao.findGZWUnits();
                        List<PageData> orgList = orgzationDao.list(null);
                        for (PageData unit : units) {
                            //集团下级企业
                            List<PageData> l = treeUtli.getChlidList(unit.getString("id"), orgList, null);
                            l.add(unit);
                            //用于查询
                            PageData p1 = new PageData();
                            List<String> orgIds = new ArrayList<>();
                            for (PageData pageData : l) {
                                orgIds.add(pageData.getString("id"));
                            }
                            p1.put("orgIds", orgIds);
                            //发债申请
                            List<PageData> applyList = bondsApplyDao.list(p1);
                            List<String> bondsApplyIds = new ArrayList<>();
                            for (PageData pageData : applyList) {
                                bondsApplyIds.add(pageData.getString("id"));
                            }
                            p1.remove("orgIds");
                            //发债发行
                            List<PageData> issueList = new ArrayList<>();
                            List<String> issueIds = new ArrayList<>();
                            if (bondsApplyIds != null && bondsApplyIds.size() > 0) {
                                p1.put("bondsApplyIds", bondsApplyIds);
                                issueList = bondissueDao.list(p1);
                            }
                            //债券偿还
                            List<PageData> repaymentList = new ArrayList<>();
                            if (issueList != null && issueList.size() > 0) {
                                p1.remove("bondsApplyIds");
                                for (PageData pageData : issueList) {
                                    issueIds.add(pageData.getString("id"));
                                }
                                if (issueIds != null && issueIds.size() > 0) {
                                    p1.put("issueIds", issueIds);
                                    repaymentList = bondsRepaymentDao.reportList(p1);
                                }
                            }
                            //集团处理好的数据
                           PageData p2= subjectUnit(applyList, issueList, repaymentList);
                           p2.put("name",unit.getString("name"));
                           list.add(p2);
                        }
                        //申报额度
                        BigDecimal b1 = new BigDecimal("0");
                        //剩余可用额度
                        BigDecimal b2 = new BigDecimal("0");
                        //发行金额
                        BigDecimal b3 = new BigDecimal("0");
                        //存续债余额
                        BigDecimal b4 = new BigDecimal("0");
                        //年度新增注册额度
                        BigDecimal b5=new BigDecimal("0");
                        //年度新增发行额度
                        BigDecimal b6=new BigDecimal("0");
                        //年内到期债权金额
                        BigDecimal b7=new BigDecimal("0");

                        for (PageData pageData : list) {
                            //申报额度
                            b1=b1.add(new BigDecimal( pageData.getString("declaredAmount")));
                            //剩余可用额度
                            b2=b2.add(new BigDecimal( pageData.getString("surplusAmount")));
                            //发行金额
                            b3=b3.add(new BigDecimal( pageData.getString("issueAmount")));
                            //存续债券余额
                            b4=b4.add(new BigDecimal( pageData.getString("balanceAmount")));
                            //年度新增发行金额
                            b5=b5.add(new BigDecimal( pageData.getString("addAmount")));
                            //年度新增发行金额
                            b6=b6.add(new BigDecimal( pageData.getString("addIssueAmount")));
                            //年度到期金额
                            b7=b7.add(new BigDecimal( pageData.getString("expireAmount")));
                        }
                        PageData p2=new PageData();
                        p2.put("name","合计");
                        p2.put("declaredAmount",b1.toPlainString());
                        p2.put("surplusAmount",b2.toPlainString());
                        p2.put("issueAmount",b3.toPlainString());
                        p2.put("balanceAmount",b4.toPlainString());
                        p2.put("addAmount",b5.toPlainString());
                        p2.put("addIssueAmount",b6.toPlainString());
                        p2.put("expireAmount",b7.toPlainString());
                        p2.put("ratio","");
                        list.add(p2);
                    }
                    //如果为集团本身
                    else if ("1".equals(org.getString("isunit"))) {
                        //得到所有企业
                        List<PageData> orgList = orgzationDao.list(null);
                        //集团下级企业
                        List<PageData> l = treeUtli.getChlidList(org.getString("id"), orgList, null);
                        l.add(org);
                        //用于查询
                        PageData p1 = new PageData();
                        List<String> orgIds = new ArrayList<>();
                        for (PageData pageData : l) {
                            orgIds.add(pageData.getString("id"));
                        }
                        p1.put("orgIds", orgIds);
                        //发债申请
                        List<PageData> applyList = bondsApplyDao.list(p1);
                        List<String> bondsApplyIds = new ArrayList<>();
                        for (PageData pageData : applyList) {
                            bondsApplyIds.add(pageData.getString("id"));
                        }
                        p1.remove("orgIds");
                        //发债发行
                        List<PageData> issueList = new ArrayList<>();
                        List<String> issueIds = new ArrayList<>();
                        if (bondsApplyIds != null && bondsApplyIds.size() > 0) {
                            p1.put("bondsApplyIds", bondsApplyIds);
                            issueList = bondissueDao.list(p1);
                        }
                        //债券偿还
                        List<PageData> repaymentList = new ArrayList<>();
                        if (issueList != null && issueList.size() > 0) {
                            p1.remove("bondsApplyIds");
                            for (PageData pageData : issueList) {
                                issueIds.add(pageData.getString("id"));
                            }
                            if (issueIds != null && issueIds.size() > 0) {
                                p1.put("issueIds", issueIds);
                                repaymentList = bondsRepaymentDao.reportList(p1);
                            }
                        }
                        //集团处理好的数据
                        PageData p2= subjectUnit(applyList, issueList, repaymentList);
                        p2.put("name",org.getString("name"));
                        list.add(p2);
                    }
                    //其他
                    else {
                        //用于查询
                        PageData p1 = new PageData();
                        List<String> orgIds = new ArrayList<>();
                        orgIds.add(org.getString("id"));
                        p1.put("orgIds", orgIds);
                        //发债申请
                        List<PageData> applyList = bondsApplyDao.list(p1);
                        List<String> bondsApplyIds = new ArrayList<>();
                        for (PageData pageData : applyList) {
                            bondsApplyIds.add(pageData.getString("id"));
                        }
                        p1.remove("orgIds");
                        //发债发行
                        List<PageData> issueList = new ArrayList<>();
                        List<String> issueIds = new ArrayList<>();
                        if (bondsApplyIds != null && bondsApplyIds.size() > 0) {
                            p1.put("bondsApplyIds", bondsApplyIds);
                            issueList = bondissueDao.list(p1);
                        }
                        //债券偿还
                        List<PageData> repaymentList = new ArrayList<>();
                        if (issueList != null && issueList.size() > 0) {
                            p1.remove("bondsApplyIds");
                            for (PageData pageData : issueList) {
                                issueIds.add(pageData.getString("id"));
                            }
                            if (issueIds != null && issueIds.size() > 0) {
                                p1.put("issueIds", issueIds);
                                repaymentList = bondsRepaymentDao.reportList(p1);
                            }
                        }
                        //集团处理好的数据
                        PageData p2= subjectUnit(applyList, issueList, repaymentList);
                        p2.put("name",org.getString("name"));
                        list.add(p2);
                    }
                }
            }
            PageData p1 = new PageData();
            p1.put("data", list);
            objResult.setPageData(p1);
            return objResult;
        } else {
            ObjResult objResult = new ObjResult(CommonCode.ERRORPARAMETER);
            objResult.setMessage("请选择维度类型！！！");
            return objResult;
        }

    }

    /**
     * 发行主体集团维度
     *
     * @param applyList     申请列表
     * @param issueList     发行列表
     * @param repaymentList 偿还列表
     * @return
     */
    private PageData subjectUnit(List<PageData> applyList,
                                 List<PageData> issueList,
                                 List<PageData> repaymentList) {
        //主体对象
        PageData pd = new PageData();
        //申报额度
        BigDecimal b1 = new BigDecimal("0");
        //剩余可用额度
        BigDecimal b2 = new BigDecimal("0");
        //发行金额
        BigDecimal b3 = new BigDecimal("0");
        //存续债余额
        BigDecimal b4 = new BigDecimal("0");
        //年度新增注册额度
        BigDecimal b5=new BigDecimal("0");
        //年度新增发行额度
        BigDecimal b6=new BigDecimal("0");
        //年内到期债权金额
        BigDecimal b7=new BigDecimal("0");

        //当前年
        LocalDateTime nowTime = LocalDateTime.now();
        int thisYear = nowTime.getYear();

        for (PageData pageData : applyList) {
            //申报额度
            String quota = pageData.getString("quota");
            if (Tools.notEmpty(quota)) {
                b1 = b1.add(new BigDecimal(quota));
                //注册时间
                String registrationDate=pageData.getString("registrationDate");
                //计算当前年度注册金额
                if(Tools.notEmpty(registrationDate)){
                    int regYear= Integer.parseInt(registrationDate.substring(0,4));
                    if(regYear==thisYear){
                        b5 = b5.add(new BigDecimal(quota));
                    }
                }
            }

            //发行
            for (PageData data : issueList) {
                if (data.getString("bondsApplyId")
                        .equals(pageData.getString("id"))) {
                    //发行额度
                    String issue_amount = data.getString("issueAmount");
                    BigDecimal b_issueAmount = new BigDecimal("0");
                    if (Tools.notEmpty(issue_amount)) {
                        b_issueAmount = new BigDecimal(issue_amount);
                        b3 = b3.add(b_issueAmount);

                        //债券起息日
                        String bondValueDate=data.getString("bondValueDate");

                        //计算当前年度发行金额
                        if(Tools.notEmpty(bondValueDate)){
                            int regYear= Integer.parseInt(bondValueDate.substring(0,4));
                            if(regYear==thisYear){
                                b6 = b6.add(new BigDecimal(issue_amount));
                            }
                        }
                        //截止日
                        String bondMaturity=data.getString("bondMaturity");
                        //计算当前年度发行金额
                        if(Tools.notEmpty(bondMaturity)){
                            int regYear= Integer.parseInt(bondMaturity.substring(0,4));
                            if(regYear==thisYear){
                                b7 = b7.add(new BigDecimal(issue_amount));
                            }
                        }
                    }
                    //已偿还金额
                    BigDecimal sumRepay = new BigDecimal("0");
                    //偿还
                    for (PageData r : repaymentList) {
                        if (r.getString("bondIssueId").equals(data.getString("id"))) {
                            if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                sumRepay = sumRepay.add(repaymentOfPrincipal);
                            }
                        }
                    }
                    //存续余额
                    BigDecimal balance = b_issueAmount.subtract(sumRepay);
                    b4 = b4.add(balance);
                }
            }
            //非超短期
            if ("5".equals(pageData.getString("bondVarieties"))) {
                b2 = b2.add(b1.subtract(b4));
            } else {
                b2 = b2.add((b1.subtract(b3)));
            }
        }
        //转换单位为亿
        b1 = b1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b2 = b2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b3 = b3.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b4 = b4.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b5 = b5.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b6 = b6.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        b7 = b7.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        //申报额度
        pd.put("declaredAmount", b1.toPlainString());
        // 剩余可用额度
        pd.put("surplusAmount", b2.toPlainString());
        //发行金额
        pd.put("issueAmount", b3.toPlainString());
        //存续债券余额
        pd.put("balanceAmount", b4.toPlainString());
        //年度新增发行金额
        pd.put("addAmount", b5.toPlainString());
        //年度新增发行额度
        pd.put("addIssueAmount", b6.toPlainString());
        //年度到期金额
        pd.put("expireAmount", b7.toPlainString());
        BigDecimal b8 = new BigDecimal("0");
        if (Double.valueOf(b1.toPlainString()) != 0) {
            b8 = b3.divide(b1, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        }
        //已发行比例
        pd.put("ratio", b8.toPlainString() + "%");
        return pd;
    }


    /**
     * 发行主体维度
     *
     * @param applyList       申请列表
     * @param issueList       发行列表
     * @param baseInfoDaoTree 企业级次
     * @param repaymentList   偿还列表
     * @return
     */
    private PageData subject(List<PageData> applyList,
                             List<PageData> issueList,
                             List<Tree> baseInfoDaoTree,
                             List<PageData> repaymentList) {
        //最后处理的返回对象
        PageData p_return = new PageData();
        //根据企业级次分组
        Map<String, List<PageData>> glist = applyList.stream().
                filter(item -> Tools.notEmpty(item.getString("enterpriseGrade"))).
                collect(Collectors.groupingBy(e -> e.getString("enterpriseGrade")));
        List<PageData> l_g = new ArrayList<>();


//        //申报额度
//        BigDecimal sum1=new BigDecimal("0");
//        //剩余可用额度
//        BigDecimal sum2=new BigDecimal("0");
//        //发行金额
//        BigDecimal sum3=new BigDecimal("0");
//        //存续债余额
//        BigDecimal sum4=new BigDecimal("0");


//        for (Tree tree :baseInfoDaoTree) {
        for (int i = 1; i <= 2; i++) {
            String code = "00100" + i;
            //企业级次
            for (String s : glist.keySet()) {
                if (code.equals(s)) {
                    PageData p = new PageData();
                    List<PageData> l = glist.get(s);
                    String name = "";
                    //企业级次
                    if (i == 1) {
                        name = "1级";
                    }
                    if (i == 2) {
                        name = "2级";
                    }

                    p.put("enterpriseGrade", name + "(" + l.size() + ")家");
                    //根据单位id分组
                    Map<String, List<PageData>> glist1 = l.stream().
                            collect(Collectors.groupingBy(e -> e.getString("issuer")));

                    //申报额度
                    BigDecimal sum_b1 = new BigDecimal("0");
                    //剩余可用额度
                    BigDecimal sum_b2 = new BigDecimal("0");
                    //发行金额
                    BigDecimal sum_b3 = new BigDecimal("0");
                    //存续债余额
                    BigDecimal sum_b4 = new BigDecimal("0");

                    List<PageData> list = new ArrayList<>();
                    //主体对象
                    for (String s1 : glist1.keySet()) {
                        PageData pd = new PageData();
                        //申报额度
                        BigDecimal b1 = new BigDecimal("0");
                        //剩余可用额度
                        BigDecimal b2 = new BigDecimal("0");
                        //发行金额
                        BigDecimal b3 = new BigDecimal("0");
                        //存续债余额
                        BigDecimal b4 = new BigDecimal("0");
                        List<PageData> l1 = glist1.get(s1);
                        for (PageData pageData : l1) {
                            //申报额度
                            String quota = pageData.getString("quota");
                            if (Tools.notEmpty(quota)) {
                                b1 = b1.add(new BigDecimal(quota));
                            }
                            //发行
                            for (PageData data : issueList) {
                                if (data.getString("bondsApplyId")
                                        .equals(pageData.getString("id"))) {
                                    //发行额度
                                    String issue_amount = data.getString("issueAmount");
                                    BigDecimal b_issueAmount = new BigDecimal("0");
                                    if (Tools.notEmpty(issue_amount)) {
                                        b_issueAmount = new BigDecimal(issue_amount);
                                        b3 = b3.add(b_issueAmount);
                                    }
                                    //已偿还金额
                                    BigDecimal sumRepay = new BigDecimal("0");
                                    //偿还
                                    for (PageData r : repaymentList) {
                                        if (r.getString("bondIssueId").equals(data.getString("id"))) {
                                            if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                                BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                                sumRepay = sumRepay.add(repaymentOfPrincipal);
                                            }
                                        }
                                    }
                                    //存续余额
                                    BigDecimal balance = b_issueAmount.subtract(sumRepay);
                                    b4 = b4.add(balance);
                                }
                            }
                            //非超短期
                            if ("5".equals(pageData.getString("bondVarieties"))) {
                                b2 = b2.add(b1.subtract(b4));
                            } else {
                                b2 = b2.add((b1.subtract(b3)));
                            }
                        }

                        //转换单位为亿
                        b1 = b1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
                        b2 = b2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
                        b3 = b3.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
                        b4 = b4.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
                        //发债主体
                        pd.put("orgName", l1.get(0).getString("issuerName"));
                        //申报额度
                        pd.put("declaredAmount", b1.toPlainString());
                        // 剩余可用额度
                        pd.put("surplusAmount", b2.toPlainString());
                        //发行金额
                        pd.put("issueAmount", b3.toPlainString());
                        //存续债券余额
                        pd.put("balanceAmount", b4.toPlainString());
                        BigDecimal b5 = new BigDecimal("0");
                        if (Double.valueOf(b1.toPlainString()) != 0) {
                            b5 = b3.divide(b1, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
                        }
                        //已发行比例
                        pd.put("ratio", b5.toPlainString() + "%");
                        list.add(pd);
                        sum_b1 = sum_b1.add(b1);
                        sum_b2 = sum_b2.add(b2);
                        sum_b3 = sum_b3.add(b3);
                        sum_b4 = sum_b4.add(b4);
                    }

//                    p.put("list",list);
//                    //申报额度
//                    p.put("sumDeclaredAmount",sum_b1.toPlainString());
//                    // 剩余可用额度
//                    p.put("sumSurplusAmount",sum_b2.toPlainString());
//                    //发行金额
//                    p.put("sumIssueAmount",sum_b3.toPlainString());
//                    //存续债券余额
//                    p.put("sumBalanceAmount",sum_b4.toPlainString());
//
//                    sum1=sum1.add(sum_b1);
//                    sum2=sum2.add(sum_b2);
//                    sum3=sum3.add(sum_b3);
//                    sum4=sum4.add(sum_b4);
//                    l_g.add(p);
                    p_return.put("list" + i, list);
                }
            }
        }

//        //申报额度
//        p_return.put("sumDeclaredAmount",sum1.toPlainString());
//        // 剩余可用额度
//        p_return.put("sumSurplusAmount",sum2.toPlainString());
//        //发行金额
//        p_return.put("sumIssueAmount",sum3.toPlainString());
//        //存续债券余额
//        p_return.put("sumBalanceAmount",sum4.toPlainString());
//        p_return.put("list",l_g);
        return p_return;
    }

    /**
     * 债券品种
     *
     * @param applyList     申请列表
     * @param issueList     发行列表
     * @param repaymentList 偿还列表
     * @return
     */
    private List<PageData> varieties(List<PageData> applyList,
                                     List<PageData> issueList,
                                     List<PageData> repaymentList
    ) {
        //根据类型分组
        Map<String, List<PageData>> glist = applyList.stream().
                filter(item -> Tools.notEmpty(item.getString("enterpriseGrade"))).
                collect(Collectors.groupingBy(e -> e.getString("bondVarieties")));
        //最后处理的返回对象
        PageData pd = new PageData();
        //申报额度
        BigDecimal sum1 = new BigDecimal("0");
        //发行金额
        BigDecimal sum2 = new BigDecimal("0");
        //存续债余额
        BigDecimal sum3 = new BigDecimal("0");

        List<PageData> l = new ArrayList<>();
        for (String type : glist.keySet()) {
            PageData p = new PageData();
            if ("0".equals(type)) {
                p.put("name", "企业债券");
            } else if ("1".equals(type)) {
                p.put("name", "公司债券");
            } else if ("2".equals(type)) {
                p.put("name", "中期票据");
            } else if ("3".equals(type)) {
                p.put("name", "短期融资券");
            } else if ("4".equals(type)) {
                p.put("name", "非定向公开债务融资工具");
            } else if ("5".equals(type)) {
                p.put("name", "超短期融资券");
            } else if ("6".equals(type)) {
                p.put("name", "永续中票");
            } else if ("7".equals(type)) {
                p.put("name", "其他");
            } else if ("8".equals(type)) {
                p.put("name", "非金融企业债券融资工具");
            } else if ("9".equals(type)) {
                p.put("name", "资产证券化");
            } else if ("10".equals(type)) {
                p.put("name", "保险资金");
            } else if ("11".equals(type)) {
                p.put("name", "保险资金投资计划");
            } else if ("12".equals(type)) {
                p.put("name", "可续期公司债券");
            }

            List<PageData> list_app = glist.get(type);
            //申报额度
            BigDecimal b1 = new BigDecimal("0");
            //发行金额
            BigDecimal b2 = new BigDecimal("0");
            //存续债余额
            BigDecimal b3 = new BigDecimal("0");
            for (PageData a : list_app) {
                //申报额度
                String quota = a.getString("quota");
                if (Tools.notEmpty(quota)) {
                    b1 = b1.add(new BigDecimal(quota));
                }
                //发行
                for (PageData data : issueList) {
                    if (data.getString("bondsApplyId")
                            .equals(a.getString("id"))) {
                        //发行额度
                        String issue_amount = data.getString("issueAmount");
                        BigDecimal b_issueAmount = new BigDecimal("0");
                        if (Tools.notEmpty(issue_amount)) {
                            b_issueAmount = new BigDecimal(issue_amount);
                            b2 = b2.add(b_issueAmount);
                        }
                        //已偿还金额
                        BigDecimal sumRepay = new BigDecimal("0");
                        //偿还
                        for (PageData r : repaymentList) {
                            if (r.getString("bondIssueId").equals(data.getString("id"))) {
                                if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                    BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                    sumRepay = sumRepay.add(repaymentOfPrincipal);
                                }
                            }
                        }
                        //存续余额
                        BigDecimal balance = b_issueAmount.subtract(sumRepay);
                        b3 = b3.add(balance);
                    }
                }
            }
            //转换单位为亿
            b1 = b1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
            b2 = b2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
            b3 = b3.divide(new BigDecimal("10000"), 6, RoundingMode.UP);

            //申报额度
            p.put("declaredAmount", b1.toPlainString());
            //发行金额
            p.put("issueAmount", b2.toPlainString());
            //存续债券余额
            p.put("balanceAmount", b3.toPlainString());
            l.add(p);
            sum1 = sum1.add(b1);
            sum2 = sum2.add(b2);
            sum3 = sum3.add(b3);
        }
//        pd.put("sumDeclaredAmount",sum1.toPlainString());
//        pd.put("sumIssueAmount",sum2.toPlainString());
//        pd.put("sumBalanceAmount",sum3.toPlainString());
//        pd.put("list",l);
        return l;
    }

    /**
     * 期限维度
     *
     * @param issueList
     * @param repaymentList
     * @return
     */
    private List<PageData> term(List<PageData> issueList,
                                List<PageData> repaymentList) {
        PageData pd = new PageData();
        //发行金额
        BigDecimal one1 = new BigDecimal("0");
        //存续债余额
        BigDecimal one2 = new BigDecimal("0");

        //发行金额
        BigDecimal oneToThree1 = new BigDecimal("0");
        //存续债余额
        BigDecimal oneToThree2 = new BigDecimal("0");

        //发行金额
        BigDecimal threeToFive1 = new BigDecimal("0");
        //存续债余额
        BigDecimal threeToFive2 = new BigDecimal("0");

        //发行金额
        BigDecimal fiveToTen1 = new BigDecimal("0");
        //存续债余额
        BigDecimal fiveToTen2 = new BigDecimal("0");

        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

        for (PageData pageData : issueList) {
//                //相差年份
            int difference = 0;
            //一年以内

            LocalDate d1 = null;
            LocalDate d2 = null;

            //起息日
            String bondValueDate = pageData.getString("bondValueDate");
            if (Tools.notEmpty(bondValueDate)) {
                d1 = LocalDate.parse(bondValueDate, fmt);
            }
            //到期日
            String bondMaturity = pageData.getString("bondMaturity");
            if (Tools.notEmpty(bondMaturity)) {
                d2 = LocalDate.parse(bondMaturity, fmt);
            }
            if (d1 != null && d2 != null) {
                Period period = Period.between(d1, d2);
                difference = period.getYears();
            }

            if (difference <= 1 && difference >= 0) {
                //发行额度
                String issue_amount = pageData.getString("issueAmount");
                BigDecimal b_issueAmount = new BigDecimal("0");
                if (Tools.notEmpty(issue_amount)) {
                    b_issueAmount = new BigDecimal(issue_amount);
                    one1 = one1.add(b_issueAmount);
                }
                //已偿还金额
                BigDecimal sumRepay = new BigDecimal("0");
                //偿还
                for (PageData r : repaymentList) {
                    if (r.getString("bondIssueId").equals(pageData.getString("id"))) {
                        if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                            BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                            sumRepay = sumRepay.add(repaymentOfPrincipal);
                        }
                    }
                }
                //存续余额
                BigDecimal balance = b_issueAmount.subtract(sumRepay);
                one2 = one2.add(balance);
            } else
                //1-3年
                if (difference > 1 && difference <= 3) {
                    //发行额度
                    String issue_amount = pageData.getString("issueAmount");
                    BigDecimal b_issueAmount = new BigDecimal(issue_amount);
                    if (Tools.notEmpty(issue_amount)) {
                        oneToThree1 = oneToThree1.add(b_issueAmount);
                    }
                    //已偿还金额
                    BigDecimal sumRepay = new BigDecimal("0");
                    //偿还
                    for (PageData r : repaymentList) {
                        if (r.getString("bondIssueId").equals(pageData.getString("id"))) {
                            if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                sumRepay = sumRepay.add(repaymentOfPrincipal);
                            }
                        }
                    }
                    //存续余额
                    BigDecimal balance = b_issueAmount.subtract(sumRepay);
                    oneToThree2 = oneToThree2.add(balance);
                } else
                    //3-5年
                    if (difference > 3 && difference <= 5) {
                        //发行额度
                        String issue_amount = pageData.getString("issueAmount");
                        BigDecimal b_issueAmount = new BigDecimal(issue_amount);
                        if (Tools.notEmpty(issue_amount)) {
                            threeToFive1 = threeToFive1.add(b_issueAmount);
                        }
                        //已偿还金额
                        BigDecimal sumRepay = new BigDecimal("0");
                        //偿还
                        for (PageData r : repaymentList) {
                            if (r.getString("bondIssueId").equals(pageData.getString("id"))) {
                                if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                    BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                    sumRepay = sumRepay.add(repaymentOfPrincipal);
                                }
                            }
                        }
                        //存续余额
                        BigDecimal balance = b_issueAmount.subtract(sumRepay);
                        threeToFive2 = threeToFive2.add(balance);

                    } else
                        //5-10年
                        if (difference > 5 && difference <= 10) {
                            //发行额度
                            String issue_amount = pageData.getString("issueAmount");
                            BigDecimal b_issueAmount = new BigDecimal(issue_amount);
                            if (Tools.notEmpty(issue_amount)) {
                                fiveToTen1 = fiveToTen1.add(b_issueAmount);
                            }

                            //已偿还金额
                            BigDecimal sumRepay = new BigDecimal("0");
                            //偿还
                            for (PageData r : repaymentList) {
                                if (r.getString("bondIssueId").equals(pageData.getString("id"))) {
                                    if (Tools.notEmpty(r.getString("repaymentOfPrincipal"))) {
                                        BigDecimal repaymentOfPrincipal = new BigDecimal(r.getString("repaymentOfPrincipal"));
                                        sumRepay = sumRepay.add(repaymentOfPrincipal);
                                    }
                                }
                            }
                            //存续余额
                            BigDecimal balance = b_issueAmount.subtract(sumRepay);
                            fiveToTen2 = fiveToTen2.add(balance);
                        }
        }

        List<PageData> l = new ArrayList<>();
        PageData p1 = new PageData();
        PageData p2 = new PageData();
        PageData p3 = new PageData();
        PageData p4 = new PageData();


        one1 = one1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        one2 = one2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);

        oneToThree1 = oneToThree1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        oneToThree2 = oneToThree2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);

        threeToFive1 = threeToFive1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        threeToFive2 = threeToFive2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);

        fiveToTen1 = fiveToTen1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
        fiveToTen2 = fiveToTen2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);

        p1.put("name", "1年（含）以内");
        p1.put("issueAmount", one1.toPlainString());
        p1.put("balanceAmount", one2.toPlainString());

        p2.put("name", "1-3年（含）以内");
        p2.put("issueAmount", oneToThree1.toPlainString());
        p2.put("balanceAmount", oneToThree2.toPlainString());

        p3.put("name", "3-5年（含）以内");
        p3.put("issueAmount", threeToFive1.toPlainString());
        p3.put("balanceAmount", threeToFive2.toPlainString());

        p4.put("name", "5-10年（含）以内");
        p4.put("issueAmount", fiveToTen1.toPlainString());
        p4.put("balanceAmount", fiveToTen2.toPlainString());


        l.add(p1);
        l.add(p2);
        l.add(p3);
        l.add(p4);
        //合计
//         BigDecimal sumIssueAmount=one1.add(oneToThree1).add(oneToThree1).add(threeToFive1).add(fiveToTen1);
//         BigDecimal sumBalanceAmount=one1.add(oneToThree2).add(oneToThree2).add(threeToFive2).add(fiveToTen2);

//         pd.put("list",l);
//         pd.put("sumIssueAmount",sumIssueAmount.toPlainString());
//         pd.put("sumBalanceAmount",sumBalanceAmount.toPlainString());
        return l;

    }

    /**
     * 年度维度
     *
     * @param issueList     发行列表
     * @param repaymentList 偿还列表
     * @return
     */
    private List<PageData> year(List<PageData> issueList,
                                List<PageData> repaymentList) {
        LocalDateTime nowTime = LocalDateTime.now();

        //当前年
        int thisYear = nowTime.getYear();
        List<PageData> l = new ArrayList<>();
        BigDecimal sum_b1 = new BigDecimal("0");
        BigDecimal sum_b2 = new BigDecimal("0");
        for (int i = 0; i <= 6; i++) {
            BigDecimal b1 = new BigDecimal("0");
            BigDecimal b2 = new BigDecimal("0");
            for (PageData pageData : issueList) {
                String year = pageData.getString("year");
                if (Tools.notEmpty(year)) {
                    int year1 = Integer.valueOf(year);
                    if (year1 == thisYear + i) {
                        String issue_amount = pageData.getString("issueAmount");
                        BigDecimal issue = new BigDecimal("0");
                        if (Tools.notEmpty(issue_amount)) {
                            issue = new BigDecimal(issue_amount);
                            b1 = b1.add(issue);
                        }
                        String extension_period = pageData.getString("extensionPeriod");
                        if (Tools.notEmpty(extension_period) && !"0".equals(extension_period)) {
                            issue = new BigDecimal(issue_amount);
                            b2 = b2.add(issue);
                        }
                    }
                }
            }
            b1 = b1.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
            b2 = b2.divide(new BigDecimal("10000"), 6, RoundingMode.UP);
            PageData p = new PageData();
            p.put("name", thisYear + i + "年");
            p.put("issueAmount", b1.toPlainString());
            p.put("extensionAmount", b2.toPlainString());
            l.add(p);
            sum_b1 = sum_b1.add(b1);
            sum_b2 = sum_b2.add(b2);
        }

        PageData p = new PageData();
//        p.put("list",l);
//        p.put("sumIssueAmount",sum_b1.toPlainString());
//        p.put("sumExtensionAmount",sum_b1.toPlainString());
        return l;
    }


//    private String getBaseName(List<Tree> l,String code){
//        String name="";
//        for (Tree tree : l) {
//            if(tree.getCode().trim().equals(code)){
//                name=tree.getCode();
//                break;
//            }
//        }
//        return name;
//    }

    /**
     * 根据id查询
     *
     * @param pd
     * @return
     */
    public ObjResult findbyid(PageData pd) {
        ObjResult objResult;
        String id = pd.getString("id");
        try {
            PageData p = bondissueDao.findbyid(id);
            PageData p2 = bondsApplyDao.findbyid(p.getString("bondsApplyId"));
            if (p2 != null) {
                p.put("applyCode", p2.getString("code"));
                p.put("issuerName", p2.getString("issuerName"));
                p.put("issuerCredit", p2.getString("issuerCredit"));
                p.put("groupCompany", p2.getString("groupCompany"));
                p.put("groupCompanyName", p2.getString("groupCompanyName"));
                p.put("quota", p2.getString("quota"));
                p.put("enterpriseGrade", p2.getString("enterpriseGrade"));
                p.put("bondVarieties", p2.getString("bondVarieties"));
            }
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
    }

    public ObjResult del_ids(List<String> ids) {
        try {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            bondissueDao.del_ids(ids);
            for (String s : ids) {
                formWorkflowService.deleteProcessInstance(s);
            }
            return objResult;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 提交单据
     *
     * @param formId 单据id
     */
    public HashMap<String, Object> commit(String formId) {
        try {
            PageData pd = bondissueDao.findbyid(formId);
            pd.put("isReport", "1");
            isData(pd);
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FLOW));
            ArrayList<String> ids = new ArrayList<>();
            ids.add(formId);
            pageData.put("id", ids);
            bondissueDao.refer(pageData);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    /**
     * 退回单据
     *
     * @param formId 单据id
     */
    public Boolean reject(String formId, int formState, String comment) {
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(formState));
        pageData.put("id", Collections.singletonList(formId));
        try {
            bondissueDao.refer(pageData);
            saveMessage(formId, false, comment);
        } catch (Exception e) {
            throw new MyRuntimeException("退回失败");
        }
//        rejectOperation(formId);
        return true;
    }

    /**
     * 单据完成后
     *
     * @param formId
     */
    public Boolean finish(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FINISH));
            pageData.put("id", Collections.singletonList(formId));
            bondissueDao.refer(pageData);
            saveMessage(formId, true, "审批通过");
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("单据流转完成时修改单据状态失败！"));
        }
        return true;
    }

    private void saveMessage(String formId, boolean approval, String comment) throws Exception{
        PageData pd = bondissueDao.findbyid(formId);
        String dataSource = pd.getString("dataSource");
        String dataSourceId = pd.getString("dataSourceId");
        if (YthConstant.DATA_NINGBO.equals(dataSource)) {
            ApprovalMessage approvalMessage = new ApprovalMessage();
            approvalMessage.setDataSourceType(YthConstant.DATA_NINGBO);
            approvalMessage.setFilingUserName(UserCache.userIdToName(TokenUtil.getTokenUserId()));
            approvalMessage.setFormType(FormTypeConstant.CQZC_BONDISSUE);
            approvalMessage.setDataSourceId(dataSourceId);
            approvalMessage.setOpinion(comment);
            approvalMessage.setIsApprove(approval ? 2 : 1);
            approvalMessage.setIsSend(1);
            approvalMessage.setFilingCode(pd.getString("code"));
            approvalMessageService.save(approvalMessage);
        }
    }

    /**
     * @param formIds 单据ids
     */
    public List<PageData> findByIds(List<String> formIds) {
        try {
            PageData pageData = new PageData();
            pageData.put("ids", formIds);
            List<PageData> forList = bondissueDao.findByIds(pageData);
            List<PageData> out = new ArrayList<>();
            for (PageData pd2 :forList){
                String unitname = pd2.getString("UNITNAME");
                pd2.put("orgName",unitname);
                out.add(pd2);
            }
            return out;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("根据单据id列表查询报表失败！"));
        }
    }

    @Override
    public List<Integer> getFormType() {
        return Collections.singletonList(CQZC_BONDISSUE);
    }

    public ObjResult remainingIssuableAmount(PageData pd) {
        try {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            PageData p = new PageData();
            p.put("remainingIssuableAmount", remainingIssuableAmount(pd.getString("bondsApplyId")));
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 剩余可发债额度
     *
     * @param bondsApplyId 注册id
     * @return
     */
    private String remainingIssuableAmount(String bondsApplyId) throws Exception {
        PageData apply = bondsApplyDao.findbyid(bondsApplyId);
        PageData p = new PageData();
        //申请id
        p.put("bondsApplyId", bondsApplyId);
        //截止日
        p.put("bondMaturity", Tools.date2Str(new Date(), "yyyy-MM-dd"));
//        p.put("status","3");
        String sumIssuance = bondissueDao.sumIssuance(p);
        //债券类型
        String quota = apply.getString("quota");
        if (Tools.isEmpty(quota)) {
            quota = "0";
        }
        if (Tools.isEmpty(sumIssuance)) {
            sumIssuance = "0";
        }
        BigDecimal b_quota = new BigDecimal(quota);
        BigDecimal b_sumIssuance = new BigDecimal(sumIssuance);
        if ("5".equals(apply.getString("bondVarieties"))) {
            //剩余可发行额度
            BigDecimal balance = b_quota.subtract(b_sumIssuance);
            //累计已偿还金额
            String sumRepay = bondsrepaymentDao.shortTermRepay(p);
            if (Tools.isEmpty(sumRepay)) {
                sumRepay = "0";
            }
            //超短期
            return new BigDecimal(sumRepay).add(balance).toPlainString();
        } else {
            //其他
            return b_quota.subtract(b_sumIssuance).toPlainString();
        }
    }


    /**
     * 退回操作
     *
     * @param id
     */
    private void rejectOperation(String id) throws Exception {
        //发行
        PageData issue = bondissueDao.findbyid(id);
        //剩余可发行金额
        String remainingIssuableAmount = issue.getString("remainingIssuableAmount");
        if (Tools.isEmpty(remainingIssuableAmount)) {
            remainingIssuableAmount = "0";
        }
        //发行金额
        String issueAmount = issue.getString("issueAmount");
        if (Tools.isEmpty(issueAmount)) {
            issueAmount = "0";
        }
        BigDecimal b_remainingIssuableAmount = new BigDecimal(remainingIssuableAmount);
        BigDecimal b_issueAmount = new BigDecimal(issueAmount);
        //回滚的剩余金额
        String Amount = b_remainingIssuableAmount.add(b_issueAmount).toPlainString();
        issue.put("remainingIssuableAmount", Amount);
        bondissueDao.edit(issue);
    }

    public String ythSubmitBatch(String data){
        YthResult ythResult = new YthResult();
        //成功的id集合
        List<String> successIds = new ArrayList<>();
        //失败的id集合
        List<String> failIds = new ArrayList<>();
        //失败的原因
        List<String> failReasons = new ArrayList<>();
        //将json字符串转换成list
        List<BondsIssue> dataList = JSON.parseArray(data, BondsIssue.class);
        if (CollectionUtil.isEmpty(dataList)){
            failReasons.add("数据为空");
            ythResult.setFailReason(StringUtils.join(failReasons, StringPool.COMMA));
            return JSON.toJSONString(ythResult);
        }

        List<BondsApply> bondsApplyList = bondsApplyService.list(Wrappers.<BondsApply>lambdaQuery()
                .eq(BondsApply::getDataSource, YthConstant.DATA_NINGBO).eq(BondsApply::getStatus, FINISH));
        Map<String, BondsApply> bondsApplyMap = bondsApplyList.stream().collect(Collectors.toMap(BondsApply::getDataSourceId, Function.identity()));
        List<BondsIssue> oldList = list(Wrappers.<BondsIssue>lambdaQuery()
                .eq(BondsIssue::getDataSource, YthConstant.DATA_NINGBO));
        Map<String, BondsIssue> oldMap = oldList.stream().collect(Collectors.toMap(BondsIssue::getDataSourceId, Function.identity()));
        List<String> cantSubmitStatus = Stream.of(String.valueOf(FINISH), String.valueOf(FLOW)).collect(Collectors.toList());
        List<String> cantSubmitList = oldList.stream().filter(item -> cantSubmitStatus.contains(item.getStatus()))
                .map(BondsIssue::getId).collect(Collectors.toList());
        Date now = DateUtil.now();
        List<BondsIssue> submitList = new ArrayList<>();
        for (BondsIssue bondsIssue : dataList){
            if (!bondsApplyMap.containsKey(bondsIssue.getBondsApplyId())){
                failIds.add(bondsIssue.getDataSourceId());
                failReasons.add(bondsIssue.getDataSourceId() + "债券申请数据不存在");
                continue;
            }
            if (cantSubmitList.contains(bondsIssue.getDataSourceId())){
                failIds.add(bondsIssue.getDataSourceId());
                failReasons.add(bondsIssue.getDataSourceId() + "该数据已提交");
                continue;
            }
            BondsApply bondsApply = bondsApplyMap.get(bondsIssue.getBondsApplyId());
            successIds.add(bondsIssue.getDataSourceId());
            bondsIssue.setBondsApplyId(bondsApply.getId());
            bondsIssue.setCode(bondsApply.getCode());
            if (oldMap.containsKey(bondsIssue.getDataSourceId())){
                bondsIssue.setId(oldMap.get(bondsIssue.getDataSourceId()).getId());
                bondsIssue.setUpdateTime(now);
            }else {
                bondsIssue.setCreateDate(now);
            }
            bondsIssue.setFormType(String.valueOf(FormTypeConstant.CQZC_BONDISSUE));
            bondsIssue.setDataSource(YthConstant.DATA_NINGBO);
            bondsIssue.setOrgId(bondsApply.getOrgId());
            bondsIssue.setCreateCompanyId(bondsApply.getCreateCompanyId());
            bondsIssue.setStatus(String.valueOf(UNREVIEWED));
            try {
                bondsIssue.setRemainingIssuableAmount(remainingIssuableAmount(bondsIssue.getBondsApplyId()));
            } catch (Exception e) {
                log.error("{},{}获取剩余可发债金额失败！", bondsIssue.getDataSourceId(), bondsIssue.getBondsApplyId());
                log.error(ExceptionUtils.getMessage(e));
            }
            submitList.add(bondsIssue);
        }

        if (CollectionUtil.isNotEmpty(submitList)){
            saveOrUpdateBatch(submitList);
            for (BondsIssue bondsIssue : submitList){
                fileService.upYthFile(bondsIssue.getAttachIds(), bondsIssue.getId());
            }
        }

        ythResult.setSuccessIds(successIds);
        ythResult.setFailIds(failIds);
        ythResult.setFailReason(StringUtils.join(failReasons, StringPool.COMMA));
        //ythResult转换成json字符串
        return JSON.toJSONString(ythResult);

    }
}